<template>
  <button @click="flag = !flag">switch</button>
  <transition
    @before-enter="EnterBefore"
    @enter="EnterActive"
    @after-enter="EnterAfter"
    @enter-cancelled="EnterCancel"
    @leave="LeaveActive"
  >
    <div class="box" v-if="flag"></div>
  </transition>
</template>
<script setup lang="ts">

// transition 组件的声明周期和钩子函数
// transition 组件采用事件绑定的形式定义对应的钩子函数
// 即在组件的不同生命周期会对应不同的事件，在生命周期的对应的时刻会触发该事件进而触发事件处理程序
// 生命周期事件：
// before-enter 进入动画开始前 enter 进入动画持续中 before-enter 进入动画结束后
// enter-cancelled 进入动画持续时被打断
// 对应的 leave 离开动画也具有对应的生命周期事件
// 生命周期事件绑定的生命周期钩子函数
// @enter = "EnterActive" const EnterActive = (el: Element, done: Function) => {}
// 所有钩子函数接受 el 参数，为 transition 组件唯一包裹的元素
// enter 和 leave 事件的钩子函数接受 done 参数，为一函数，在钩子函数中调用 done 表明动画完成
// 默认不接受 done 参数时，进入生命周期会立即触发 done

// transition 生命周期钩子函数常与 js 第三方动画库连用，采用 js 形式定义动画效果
// gsap js 第三方动画库
// 安装 npm install gsap -S 发布阶段要使用
// 导入 import gsap from 'gasp'
// 调用：
// 在 before-enter 生命周期钩子函数中调用 gsap.set() 设置进入动画开始前的起始样式
// 第一个参数为设置样式的元素，第二个参数为 css 样式对象
// gsap.set(el: Element, obj: CSSStyleObject)
// 在 enter 和 leave 生命周期钩子函数中调用 gsap.to() 设置动画运行时的最终的样式
// 动画本身效果是由 gsap 的方法决定
// 第一个参数为设置样式的元素，第二个参数为 css 样式对象 + onComplete 方法
// gsap 动画效果结束后，会调用 onComplete 方法定义的回调，其中调用 done 方法，表示动画完成
// gsap.to(el: Element, obj:{
// CSSStyleObject,
// OnComplete: done: GSAP.Callback
// })



import { ref } from 'vue'
// 导入第三方 JS 动画库
import gsap from 'gsap'
const flag = ref<boolean>(false)

const EnterBefore = (el: Element) => {
  console.log('进入动画开始前')
  // 调用 gsap 的 set 方法，第一个参数为动画设置的元素，第二个参数为配置对象
  // 配置对象即为 style 对象，为进入动画的起始样式
  // 即在进入动画开始前，调用 gsap.set 方法，设置起始样式
  gsap.set(el, {
    width: '0px',
    height: '0px',
  })
}
// 进入动画运行时的钩子函数
// 参数 el 为 transition 组件唯一包裹的标签
// done 函数，在该钩子函数中触发该函数，会结束该钩子函数，表明进入动画运行完成
// 默认不传参数 done 时，该声明周期立即触发 done 即进入动画立即完成
const EnterActive = (el: Element, done: GSAPCallback) => {
  console.log('进入动画运行中')
  console.log(el)
  // setTimeout(done, 3000)

  // 在进入动画运行时，调用 gsap 的 to 方法，设置进入动画运行后的目标静态样式
  // 参数 el 为 transition 组件唯一包裹的标签
  // 配置对象中出 style 对象属性还包含 onComplete 属性，指定回调
  // 即进入动画完成后会触发 onComplete 回调，表明动画已完成
  gsap.to(el, {
    width: '200px',
    height: '200px',
    backgroundColor: 'red',
    onComplete: done,
  })
}
const EnterAfter = () => {
  console.log('进入动画结束后')
}
const EnterCancel = () => {
  console.log('进入动画运行时被打断')
}
const LeaveActive = (el: Element, done: GSAPCallback) => {
  gsap.to(el, {
    width: '0px',
    height: '0px',
    onComplete: done,
  })
}
</script>
<style lang="less" scoped>
// .box {
//   height: 200px;
//   width: 200px;
//   background-color: red;
// }
</style>
